/***************************************************
 @Name :        小铭同学
 @Time :        2025-09-03
 @Email :       LiaoMingWJ233@163.com
 @Comment :     扩展板 设备驱动
 @FileName :    hal_mp1a.c
 @Version :     1.0
****************************************************/


#include <hal_device.h>

// #ifdef PLAT_MP1A

int led_init()
{
    return 0;
}

int led_on(int nr)
{
    int fd = 0;

    switch (nr)
    {
    case led1:
        fd = open(LED_PATH_1, O_WRONLY);
        break;
    case led2:
        fd = open(LED_PATH_2, O_WRONLY);
        break;
    case led3:
        fd = open(LED_PATH_3, O_WRONLY);
        break;
    case led4:
        fd = open(LED_PATH_4, O_WRONLY);
        break;
    case led5:
        fd = open(LED_PATH_5, O_WRONLY);
        break;
    case led6:
        // fd = open(LED_PATH_1, O_WRONLY);
        break;
    }

    write(fd, "1", 1); // LED_ON
    close(fd);
    return 0;
}

int led_off(int nr)
{
    int fd = 0;

    switch (nr)
    {
    case led1:
        fd = open(LED_PATH_1, O_WRONLY);
        break;
    case led2:
        fd = open(LED_PATH_2, O_WRONLY);
        break;
    case led3:
        fd = open(LED_PATH_3, O_WRONLY);
        break;
    case led4:
        fd = open(LED_PATH_4, O_WRONLY);
        break;
    case led5:
        fd = open(LED_PATH_5, O_WRONLY);
        break;
    case led6:
        // fd = open(LED_PATH_1, O_WRONLY);
        break;
    }

    write(fd, "0", 1); // LED_OFF
    close(fd);
    return 0;
}

int led_all_on()
{
    int fd1, fd2, fd3, fd4, fd5;
    fd1 = open(LED_PATH_1, O_WRONLY);
    fd2 = open(LED_PATH_2, O_WRONLY);
    fd3 = open(LED_PATH_3, O_WRONLY);
    fd4 = open(LED_PATH_4, O_WRONLY);
    fd5 = open(LED_PATH_5, O_WRONLY);

    write(fd1, "1", 1);
    write(fd2, "1", 1);
    write(fd3, "1", 1);
    write(fd4, "1", 1);
    write(fd5, "1", 1);

    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd5);

    return 0;
}

int led_all_off()
{
    int fd1, fd2, fd3, fd4, fd5;
    fd1 = open(LED_PATH_1, O_WRONLY);
    fd2 = open(LED_PATH_2, O_WRONLY);
    fd3 = open(LED_PATH_3, O_WRONLY);
    fd4 = open(LED_PATH_4, O_WRONLY);
    fd5 = open(LED_PATH_5, O_WRONLY);

    write(fd1, "0", 1);
    write(fd2, "0", 1);
    write(fd3, "0", 1);
    write(fd4, "0", 1);
    write(fd5, "0", 1);

    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd5);

    return 0;
}

int beep_fd;
struct input_event event;
int beep_init()
{

    beep_fd = open(BEEP_PATH, O_RDWR);
    if (beep_fd < 0)
    {
        perror("open beep error\n");
    }
    return 0;
}

int beep_on()
{
    event.type = EV_SND;
    event.code = SND_TONE;
    event.value = 1000;

    int ret = write(beep_fd, &event, sizeof(struct input_event));
    if (ret < 0)
    {
        perror("write to open beep error\n");
    }
    return 0;
}

int beep_off()
{
    event.type = EV_SND;
    event.code = SND_TONE;
    event.value = 0;

    int ret = write(beep_fd, &event, sizeof(struct input_event));
    if (ret < 0)
    {
        perror("write to open beep error\n");
    }
    return 0;
}

int set_pwm(int value)
{
    event.type = EV_SND;
    event.code = SND_TONE;
    event.value = value;
    int ret = write(beep_fd, &event, sizeof(struct input_event));
    if (ret < 0)
    {
        perror("write to open beep error\n");
    }
    return 0;
}

void beep_close()
{
    close(beep_fd);
}

int fan_init()
{
    return 0;
}

int fan_pwm(char *buf)
{
    int fd;
    fd = open("/sys/class/hwmon/hwmon1/pwm1", O_RDWR);
    if (fd < 0)
    {
        perror("open fan  error\n");
    }
    printf("buy:%s\n", buf);
    int ret = write(fd, buf, sizeof(buf));
    if (ret < 0)
    {
        perror("write to open fan error\n");
    }
    close(fd);
    return 0;
}

int fan_off()
{
    int fd;
    fd = open("/sys/class/hwmon/hwmon1/pwm1", O_RDWR);
    if (fd < 0)
    {
        perror("open fan  error\n");
    }

    char *buf = "0";
    int ret = write(fd, buf, sizeof(buf));
    if (ret < 0)
    {
        perror("write to open fan error\n");
    }
    close(fd);
    return 0;
}

int vibrator_init()
{
    return 0;
}

int vibrator_on(int frequency)
{
    int fd;
    int length = 5000;
    int strong_magnitude = frequency;
    fd = open(VIBRATOR, O_RDWR);
    if (fd < 0)
    {
        printf("Error opening file '%s': %s\n", VIBRATOR, strerror(errno));
        return 1;
    }

    if (strong_magnitude > 0xFFFF)
        strong_magnitude = 0xFFFF;
    if (strong_magnitude < 000000)
        strong_magnitude = 000000;

    int num_effects;
    if (ioctl(fd, EVIOCGEFFECTS, &num_effects) < 0)
    {
        printf("Error getting number of effects playable at the same time: %s\n", strerror(errno));
        return 1;
    }

    printf("%d effects playable at the same time\n", num_effects);

    // 如果效果数量达到上限，则停�?�当前�?�在��?放的效果并清空所有效��?
    if (num_effects >= MAX_EFFECTS)
    {
        struct input_event stop = {
            .type = EV_FF,
            .code = -1,
            .value = 0};
        if (write(fd, (const void *)&stop, sizeof(stop)) < 0)
        {
            printf("Error stopping effect: %s\n", strerror(errno));
            return 1;
        }

        for (int id = 0; id < num_effects; id++)
        {
            struct input_event stop_effect = {
                .type = EV_FF,
                .code = id,
                .value = 0};
            if (write(fd, (const void *)&stop_effect, sizeof(stop_effect)) < 0)
            {
                printf("Error stopping effect: %s\n", strerror(errno));
                return 1;
            }
        }
        num_effects = 0; // 将效果数量重��?��?0
    }

    struct ff_effect effect;
    effect.type = FF_RUMBLE;
    effect.id = -1;
    effect.u.rumble.strong_magnitude = strong_magnitude;
    effect.u.rumble.weak_magnitude = 0;
    effect.replay.length = length;
    effect.replay.delay = 0;

    if (ioctl(fd, EVIOCSFF, &effect) < 0)
    {
        printf("Error creating new effect: %s\n", strerror(errno));
        return 1;
    }
    printf("New effect ID: %d\n", effect.id);

    struct input_event play = {
        .type = EV_FF,
        .code = effect.id,
        .value = 1};

    if (write(fd, (const void *)&play, sizeof(play)) < 0)
    {
        printf("Error writing effect to file: %s\n", strerror(errno));
        return 1;
    }

    printf("Wrote effect\n");
    sleep(3);

    // 停�?�振动效��?
    struct input_event stop = {
        .type = EV_FF,
        .code = effect.id,
        .value = 0};
    if (write(fd, (const void *)&stop, sizeof(stop)) < 0)
    {
        printf("Error stopping effect: %s\n", strerror(errno));
        return 1;
    }
    printf("Stopped effect\n");
    close(fd);
    return 0;
}

void vibrator_close()
{
}

struct gpiohandle_request req1;
struct gpiohandle_data data1;
int ret1 = 0;
int fd1 = 0;

struct gpiohandle_request req2;
struct gpiohandle_data data2;
int ret2 = 0;
int fd2 = 0;

struct gpiohandle_request req3;
struct gpiohandle_data data3;
int ret3 = 0;
int fd3 = 0;

void key_init() {}

int is_Key1_clicked()
{
    fd1 = open("/dev/gpiochip5", 0);
    if (fd1 < 0)
    {
        perror("open key2  error\n");
    }
    req1.lineoffsets[0] = 9;
    req1.flags = GPIOHANDLE_REQUEST_INPUT;
    memcpy(req1.default_values, &data1, sizeof(req1.default_values));
    strcpy(req1.consumer_label, KEY1);
    req1.lines = 1;

    ret1 = ioctl(fd1, GPIO_GET_LINEHANDLE_IOCTL, &req1);
    if (ret1 < 0)
    {
        perror("Failed to issue GET LINEHANDLE IOCTL");
    }
    ret1 = ioctl(req1.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data1);
    if (ret1 < 0)
    {
        perror("Failed to issue GPIOHANDLE_SET_LINE_VALUES_IOCTL");
    }
    close(req1.fd);
    close(fd1);
    return data1.values[0];
}

int is_Key2_clicked()
{
    fd2 = open("/dev/gpiochip5", 0);
    if (fd2 < 0)
    {
        perror("open key2  error\n");
    }
    req2.lineoffsets[0] = 7;
    req2.flags = GPIOHANDLE_REQUEST_INPUT;
    memcpy(req2.default_values, &data2, sizeof(req2.default_values));
    strcpy(req2.consumer_label, KEY2);
    req2.lines = 1;

    ret2 = ioctl(fd2, GPIO_GET_LINEHANDLE_IOCTL, &req2);
    if (ret2 < 0)
    {
        perror("Failed to issue GET LINEHANDLE IOCTL");
    }
    ret2 = ioctl(req2.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data2);
    if (ret2 < 0)
    {
        perror("Failed to issue GPIOHANDLE_SET_LINE_VALUES_IOCTL");
    }
    close(req2.fd);
    close(fd2);
    return data2.values[0];
}

int is_Key3_clicked()
{
    fd3 = open("/dev/gpiochip5", 0);
    if (fd3 < 0)
    {
        perror("open key3  error\n");
    }
    req3.lineoffsets[0] = 8;
    req3.flags = GPIOHANDLE_REQUEST_INPUT;
    memcpy(req3.default_values, &data3, sizeof(req3.default_values));
    strcpy(req3.consumer_label, KEY3);
    req3.lines = 1;

    ret3 = ioctl(fd3, GPIO_GET_LINEHANDLE_IOCTL, &req3);
    if (ret3 < 0)
    {
        perror("Failed to issue GET LINEHANDLE IOCTL");
    }
    ret3 = ioctl(req3.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data3);
    if (ret3 < 0)
    {
        perror("Failed to issue GPIOHANDLE_SET_LINE_VALUES_IOCTL");
    }
    close(req3.fd);
    close(fd3);
    return data3.values[0];
}

// struct gpiohandle_request io_req1;
// struct gpiohandle_data data1;
int io_ret1;
int io_fd1;

// struct gpiohandle_request req2;
// struct gpiohandle_data data2;
int io_ret2 = 0;
int io_fd2 = 0;

// struct gpiohandle_request req3;
// struct gpiohandle_data data3;
int io_ret3 = 0;
int io_fd3 = 0;

int io_init()
{
    return 0;
}

// 读取特定GPIO引脚的值。�?�果GPIO引脚��?高电平，��?能返��?1（或者其他非零值）。�?�果GPIO引脚��?低电平，将返��?0。�?�果在�?�取过程��?发生错�??，将返回-1��?
int get_io_frame()
{
    io_fd1 = open("/dev/gpiochip5", 0);
    if (io_fd1 < 0)
    {
        perror("open Flame error\n");
        return -1;
    }
    // 设置请求的GPIO引脚
    req1.lineoffsets[0] = 5;
    // 设置请求的标志为输入，表示将这个引脚设置为输入模��?
    req1.flags = GPIOHANDLE_REQUEST_INPUT;
    // 复制data1到�?�求的默认��?
    memcpy(req1.default_values, &data1, sizeof(req1.default_values));
    // 设置请求的标签为FRAME，这��?标�?�可以是任何字�?�串，用于标识�?�求的源��?
    strcpy(req1.consumer_label, FRAME);
    // 设置请求的GPIO线数��?1，表示只请求一个GPIO��?
    req1.lines = 1;
    // 调用ioctl函数，发送一��?获取GPIO线句柄的请求。�?�果成功，�?�求的结构体（req1）将��?��?��?
    io_ret1 = ioctl(io_fd1, GPIO_GET_LINEHANDLE_IOCTL, &req1);
    if (io_ret1 < 0)
    {
        perror("Failed to issue GET LINEHANDLE IOCTL");
        return -1;
    }
    // 调用ioctl函数，发送一��?获取GPIO线值的请求。�?�果成功，data1将�??��?��?
    io_ret1 = ioctl(req1.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data1);
    if (ret1 < 0)
    {
        perror("Failed to issue GPIOHANDLE_GET_LINE_VALUES_IOCTL");
        return -1;
    }
    close(req1.fd);
    close(io_fd1);
    return data1.values[0];
}

int get_io_infread()
{
    io_fd2 = open("/dev/gpiochip7", 0);
    if (io_fd2 < 0)
    {
        perror("open Infread error\n");
        return -1;
    }

    req2.lineoffsets[0] = 6;
    req2.flags = GPIOHANDLE_REQUEST_INPUT;
    memcpy(req2.default_values, &data2, sizeof(req2.default_values));
    strcpy(req2.consumer_label, INFREAD);
    req2.lines = 1;

    io_ret2 = ioctl(io_fd2, GPIO_GET_LINEHANDLE_IOCTL, &req2);
    if (io_ret2 < 0)
    {
        perror("Failed to issue GET LINEHANDLE IOCTL");
        return -1;
    }
    io_ret2 = ioctl(req2.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data2);
    if (io_ret2 < 0)
    {
        perror("Failed to issue GPIOHANDLE_GET_LINE_VALUES_IOCTL");
        return -1;
    }
    close(req2.fd);
    close(io_fd2);
    return data2.values[0];
}

int get_io_photoswitch()
{
    io_fd3 = open("/dev/gpiochip4", 0);
    if (io_fd3 < 0)
    {
        perror("open photoswitch error\n");
        return -1;
    }
    req3.lineoffsets[0] = 15;
    req3.flags = GPIOHANDLE_REQUEST_INPUT;
    memcpy(req3.default_values, &data3, sizeof(req3.default_values));
    strcpy(req3.consumer_label, PHOTOSWITCH);
    req3.lines = 1;

    io_ret3 = ioctl(io_fd3, GPIO_GET_LINEHANDLE_IOCTL, &req3);
    if (io_ret3 < 0)
    {
        perror("Failed to issue GET LINEHANDLE IOCTL");
        return -1;
    }
    io_ret3 = ioctl(req3.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data3);
    if (io_ret3 < 0)
    {
        perror("Failed to issue GPIOHANDLE_SET_LINE_VALUES_IOCTL");
        return -1;
    }
    close(req3.fd);
    close(io_fd3);
    return data3.values[0];
}

// #endif
